package com.wyvoid.forum.dao.hibernate;

import com.wyvoid.core.persistent.Pagination;
import com.wyvoid.core.persistent.hibernate.HibernateDAO;
import com.wyvoid.core.persistent.hibernate.HibernatePage;
import com.wyvoid.forum.dao.IPostDAO;
import com.wyvoid.forum.domain.Post;
import com.wyvoid.forum.domain.Topic;
import com.wyvoid.forum.web.search.SearchBean;
import com.sohospace.lucene.analysis.xanalyzer.XQueryAnalyzer;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.FullTextQuery;
import org.hibernate.Session;
import org.hibernate.HibernateException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.*;
import org.apache.lucene.index.Term;
import org.apache.lucene.document.DateTools;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.orm.hibernate3.HibernateCallback;

import java.util.List;
import java.util.Calendar;
import java.sql.SQLException;

/**
 * 论坛信息Hibernate数据处理实现
 *
 * @author wyvoid
 * @version $Revision: 1.11 $ $Date: 2006/07/29 15:46:46 $
 * @link www.wyvoid.com
 */
public class PostDAO extends HibernateDAO<Post> implements IPostDAO {


    /**
     * 列表全部的帖子
     *
     * @param topicId    主题编号
     * @param pagination 分页参数
     * @return QueryResult 帖子集合
     */
    public HibernatePage<Post> getPosts(final long topicId, final Pagination pagination) {
        String hql = "from Post where topicId=?";
        return doQuery(hql, true, pagination, topicId);
    }

    /**
     * 取得贴子总数
     *
     * @return
     * @
     */
    public long countPost() {
        return doQueryCount("select count(p.id) from Post as p");
    }

    /**
     * 根据论坛编号取得贴子总数
     *
     * @param forumId 论坛编号
     * @return
     * @
     */
    public long countPost(int forumId) {
        return doQueryCount("select count(p.id) from Post as p where p.forumId='" + forumId + "'");
    }

    /**
     * 根据论坛编号取得今日贴子总数
     *
     * @param forumId 论坛编号
     * @return
     * @
     */
    public long countTodayPost(int forumId, String beginTime, String endTime) {
        return doQueryCount("select count(p.id) from Post as p where p.forumId='" + forumId + "' and p.dateCreated between '" + beginTime + "' and '" + endTime + "'");
    }

    /**
     * 根据主题批量删除帖子
     *
     * @param topicId 主题编号
     * @
     */
    public void deletePosts(int topicId) {
        super.executeHsql("delete Post where topicId='" + topicId + "'");
    }

    /**
     * 移动帖子
     *
     * @param topicId 主题编号
     * @param forumId 论坛编号
     * @
     */
    public void movePost(int topicId, int forumId) {
        super.executeHsql("update Post set forumId='" + forumId + "' where topicId=" + topicId);
    }

    public HibernatePage<Post> searchPosts(SearchBean searchBean, Pagination pagination) {
        FullTextSession textSession = Search.createFullTextSession(this.getSession());
        BooleanQuery comboQuery = new BooleanQuery();
        if (StringUtils.isNotBlank(searchBean.getKey())) {
            String keyWord=searchBean.getKey();
            if (keyWord.indexOf(" ") > 0) {
                String[] s = keyWord.split(" ");
                keyWord = "";
                int x = 0;
                for (String s1 : s) {
                    s1 = "title:"+s1+"";
                    keyWord += s1;
                    if (x < s.length - 1) keyWord += " and ";
                    x++;
                }
            }

            QueryParser parser = new QueryParser("content", new XQueryAnalyzer());
            org.apache.lucene.search.Query luceneQuery;
            try {
                luceneQuery = parser.parse(keyWord);
                comboQuery.add(luceneQuery, BooleanClause.Occur.MUST);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        if (searchBean.getBeforeTimes() != 0) {
            Calendar now = Calendar.getInstance();
            Calendar lower = (Calendar) now.clone();
            lower.add(Calendar.SECOND, -searchBean.getBeforeTimes());
            if (searchBean.getBefore() == 1) {
                now = (Calendar) lower.clone();
                lower.setTimeInMillis(0);
            }
            RangeQuery rangeQuery = new RangeQuery(new Term("createTime", DateFormatUtils.format(lower.getTime(), "yyyyMMdd")), new Term("createTime", DateFormatUtils.format(now.getTime(), "yyyyMMdd")), true);
            comboQuery.add(rangeQuery, BooleanClause.Occur.MUST);
        }


        if (!ArrayUtils.isEmpty(searchBean.getForumIds())&&!ArrayUtils.contains(searchBean.getForumIds(), 0)) {
            for (long fid : searchBean.getForumIds()) {
                TermQuery termQuery = new TermQuery(new Term("forumId", fid + ""));
                comboQuery.add(termQuery, BooleanClause.Occur.MUST);
            }
        }

        Sort sort;
        boolean desc = StringUtils.equals(searchBean.getAscdesc(),"desc");
        if (StringUtils.equals(searchBean.getOrderby(),"lastPost")) {
            sort = new Sort(new SortField("createTime", desc));
        } else {
            sort = new Sort(new SortField("createTime", desc));
        }


        FullTextQuery fullTextQuery = textSession.createFullTextQuery(comboQuery, Post.class);
        fullTextQuery.setSort(sort);
        int total = fullTextQuery.getResultSize();
        List<Post> result = fullTextQuery.list();
        return new HibernatePage(result, total, pagination.getPageNumber(), pagination.getPageSize());
    }

    public void indexAll() {
        FullTextSession fullTextSession = Search.createFullTextSession(this.getSession());
        List<Post> posts = getHibernateTemplate().loadAll(Post.class);
        for (Post post : posts) {
            fullTextSession.index(post);
        }
    }
}